iT邦幫忙

第 11 屆 iThome 鐵人賽

DAY 14
1

14 - JS Reference VS Copy

俗話說的好,一天一蘋果,醫生遠離我

一天一 JS,What the f*ck JavaScript?

small steps every day - 記錄著新手村日記

完成目標

今天來做 JavaScript reference 與 copy 了解 JavaScript 是怎麼運作的

就依下面的題目一題一題做吧!(我也看不懂如何分題目...

index_START.html

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>JS Reference VS Copy</title>
</head>
<body>

  <script>
    // start with strings, numbers and booleans

    // Let's say we have an array
    const players = ['Wes', 'Sarah', 'Ryan', 'Poppy'];

    // and we want to make a copy of it.

    // You might think we can just do something like this:

    // however what happens when we update that array?

    // now here is the problem!

    // oh no - we have edited the original array too!

    // Why? It's because that is an array reference, not an array copy. They both point to the same array!

    // So, how do we fix this? We take a copy instead!

    // one way

    // or create a new array and concat the old one in

    // or use the new ES6 Spread

    // now when we update it, the original one isn't changed

    // The same thing goes for objects, let's say we have a person object

    // with Objects
    const person = {
      name: 'Wes Bos',
      age: 80
    };

    // and think we make a copy:

    // how do we take a copy instead?

    // We will hopefully soon see the object ...spread

    // Things to note - this is only 1 level deep - both for Arrays and Objects. lodash has a cloneDeep method, but you should think twice before using it.

  </script>

</body>
</html>

JS - step by step

首先,首先,從字串、數字、布林開始:

<script>
		// start with strings, numbers and booleans
		
    let age = 100;
    let age2 = age;
    console.log(age, age2);
    // 100 100

    age = 200;
    console.log(age, age2);
    // 200 100

    let name = 'Wes';
    let name2 = name;
    console.log(name, name2);
    // Wes Wes

    name = 'wesley';
    console.log(name, name2);
    //wesley Wes

</script>

複製陣列的三種方式

  1. Array.prototype.slice():https://tinyurl.com/y386jf7b
  2. Array.prototype.concat():https://tinyurl.com/y4zx2jz8
  3. ES6:[...]
<script>
    // 陣列
    const players = ['Wes', 'Sarah', 'Ryan', 'Poppy'];

    // 我們希望複製這個陣列
    const team = players;

    console.log(players, team);
    // 也許你應該覺得就長這樣吧:
    // team[3] = 'Lux';

    // 但是當我們更新陣列的時候呢?

    // 問題就...

    // 我們原本的陣列也被更改到了~

    // 因為這不是複製、都在記憶體中對應到同一個陣列

    // one way
    const team2 = players.slice();

    // second 
    const team3 = [].concat(players);

    // or use the new ES6 Spread
    const team4 = [...players];
    team4[3] = 'heeee hawww';
    console.log(team4);
    //["Wes", "Sarah", "Ryan", "heeee hawww"]

</script>

物件的複製

  1. Object.assign():https://tinyurl.com/j74djep
  2. JSON.parse(JSON.stringify()):https://tinyurl.com/yyzultt5
    • 注意這種字串化的寫法,如果原本被複製的物件有 function,那新的複製物件呼叫 function 會失效,反之 Object.assign() 則不會
<script>
		// with Objects
    const person = {
      name: 'Wes Bos',
      age: 80
    };

    // and think we make a copy:
    // const captain = person;
    // captain.number = 99;

    // how do we take a copy instead?
    const cap2 = Object.assign({}, person, { number: 99, age: 12 });
    console.log(cap2);

    // We will hopefully soon see the object ...spread
    // const cap3 = {...person};

    // Things to note - this is only 1 level deep - both for Arrays and Objects. lodash has a cloneDeep method, but you should think twice before using it.

    const wes = {
      name: 'Wes',
      age: 100,
      social: {
        twitter: '@wesbos',
        facebook: 'wesbos.developer'
      }
    };

    console.clear();
    console.log(wes);

    const dev = Object.assign({}, wes);
    const dev2 = JSON.parse(JSON.stringify(wes));

</script>

JS - Final

<script>
    // start with strings, numbers and booleans
    // let age = 100;
    // let age2 = age;
    // console.log(age, age2);
    // age = 200;
    // console.log(age, age2);

    // let name = 'Wes';
    // let name2 = name;
    // console.log(name, name2);
    // name = 'wesley';
    // console.log(name, name2);

    // Let's say we have an array
    const players = ['Wes', 'Sarah', 'Ryan', 'Poppy'];

    // and we want to make a copy of it.
    const team = players;

    console.log(players, team);
    // You might think we can just do something like this:
    // team[3] = 'Lux';

    // however what happens when we update that array?

    // now here is the problem!

    // oh no - we have edited the original array too!

    // Why? It's because that is an array reference, not an array copy. They both point to the same array!

    // So, how do we fix this? We take a copy instead!
    const team2 = players.slice();

    // one way

    // or create a new array and concat the old one in
    const team3 = [].concat(players);

    // or use the new ES6 Spread
    const team4 = [...players];
    team4[3] = 'heeee hawww';
    console.log(team4);

    const team5 = Array.from(players);

    // now when we update it, the original one isn't changed

    // The same thing goes for objects, let's say we have a person object

    // with Objects
    const person = {
      name: 'Wes Bos',
      age: 80
    };

    // and think we make a copy:
    // const captain = person;
    // captain.number = 99;

    // how do we take a copy instead?
    const cap2 = Object.assign({}, person, { number: 99, age: 12 });
    console.log(cap2);

    // We will hopefully soon see the object ...spread
    // const cap3 = {...person};

    // Things to note - this is only 1 level deep - both for Arrays and Objects. lodash has a cloneDeep method, but you should think twice before using it.

    const wes = {
      name: 'Wes',
      age: 100,
      social: {
        twitter: '@wesbos',
        facebook: 'wesbos.developer'
      }
    };

    console.clear();
    console.log(wes);

    const dev = Object.assign({}, wes);
    const dev2 = JSON.parse(JSON.stringify(wes));

</script>

本刊同步於個人網站:http://chestertang.site/

本次範例程式碼原作者來源:https://tinyurl.com/yavm5f5n


上一篇
新手村13 - Slide in on Scroll
下一篇
新手村15 - LocalStorage
系列文
新手村-30 Day JS Coding Challenge30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言